﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace AutoCode.SqlServer
{
    /// <summary>
    /// 生成工具类
    /// </summary>
    public class GenerateUtil
    {

        /// <summary>
        /// 单表生成
        /// </summary>
        /// <param name="codePath">生成路径</param>
        /// <param name="tlpPath">模板路径</param>
        /// <param name="tableName">表名</param>
        /// <param name="tableChName">表中文名</param>
        /// <param name="fileExt">生成文件后缀名</param>
        public static void MakeSingleTable(string codePath, string tlpPath, string tableName, string tableChName, string fileExt)
        {
            DataTable dtCs = DBHelper.GetTableBySql(MsSqlCommand.GetColumnNames(tableName));
            Dictionary<string, string> columns = new Dictionary<string, string>(); //列名集合 key=类名，value=类型
            for (int i = 0; i < dtCs.Rows.Count; i++)
            {
                columns.Add(Convert.ToString(dtCs.Rows[i][0]).ToLower(), AppConst.CONST_DBTYPES[Convert.ToString(dtCs.Rows[i][1]).ToLower()]);
            }
            string tlpContent = FileUtils.ReadFile(tlpPath); //模板内容
            string tlpName = Path.GetFileName(tlpPath).Replace(".t", ""); //模板名称=$NAMESPACE
            string tabName_FirstUp = MyUtils.TitleCase(tableName);//表名（首字母大写）=$TABLE | tabelName=$TABLE_LOWER
            StringBuilder setAllColumns = new StringBuilder(); //= $SET_ALLCOLUMNS
            StringBuilder setAllColumnsRemoveFK = new StringBuilder(); //= $SET_ALLCOLUMNS_R_FK
            StringBuilder summaryAllColumns = new StringBuilder(); //= $SUMMARY_ALLCOLUMNS
            StringBuilder paramColumnsTypes = new StringBuilder(); //= $PARAMCOLUMNS_TYPES
            StringBuilder paramColumnsStringRemoveFK = new StringBuilder(); //=$PARAMCOLUMNS_STRING_R_FK
            StringBuilder paramColumnsString = new StringBuilder(); //=$PARAMCOLUMNS_STRING
            StringBuilder paramColumns = new StringBuilder(); //= $PARAMCOLUMNS
            StringBuilder requestInitParams = new StringBuilder(); //= $REQUEST_INIT_ALLCOLUMNS_PARAMS 初始化所有列的请求Request参数
            StringBuilder requestConvertParams = new StringBuilder(); //=$REQUEST_CONVERT_COLUMNS_PARAMS 转换列的非string的Request参数
            string fkDataType = "int";  //主键数据类型
            int count = 0;
            foreach (var column in columns) //循环列名
            {
                string type = column.Value.ToLower();
                string name = column.Key;
                setAllColumns.Append(string.Format("\r\nd.{0} = {0};", name));
                summaryAllColumns.Append(string.Format("\r\n/// <param name=\"{0}\"></param>;", name));
                paramColumnsTypes.Append(string.Format(" {0} {1},", type, name));
                paramColumnsString.Append(string.Format(" \"{0}\",", name));
                paramColumns.Append(string.Format(" {0},", name));
                if (count != 0)
                {
                    paramColumnsStringRemoveFK.Append(string.Format(" \"{0}\",", name));
                    setAllColumnsRemoveFK.Append(string.Format("\r\nd.{0} = {0};", name));
                }
                else
                {
                    fkDataType = type;
                }
                if (type == "string")
                {
                    requestInitParams.Append(string.Format("\r\nstring {0} = Request[\"{0}\"];", name));
                }
                else
                {
                    requestInitParams.Append(string.Format("\r\n{0} {1} = 0;", type, name));
                    requestConvertParams.Append(string.Format("\r\n{0} = {1}.Parse(Request[\"{0}\"]);", name, type));
                }
                count++;
            }
            //是否物理删除判断
            if (tlpContent.Contains("$CODE_ISDEL"))
            {
                string upCode = "\r\n$TABLE_LOWER d = new $TABLE_LOWER();\r\nd.id = id;\r\nd.state = (int)AppEnum.UnityEnum.已删除;\r\nresult = EFDBHelper.Update(d, new string[] { \"state\" }, true, db);";
                string delCode = "\r\nvar data = db.$TABLE_LOWER.Where(d => d.id == id).FirstOrDefault();\r\ndb.$TABLE_LOWER.Remove(data);\r\ndb.SaveChanges();\r\nid = 1;";
                if (columns.ContainsKey("state"))
                { //逻辑删除
                    tlpContent = tlpContent.Replace("$CODE_ISDEL", upCode);
                }
                else
                { //物理删除
                    tlpContent = tlpContent.Replace("$CODE_ISDEL", delCode);
                    tlpContent = tlpContent.Replace("d.id != -1", "d.id != -1");
                }
            }
            //替换IF标签
            foreach (Match item in Regex.Matches(tlpContent, @"\$IF.*?\$"))
            {
                if (columns.Keys.Contains(AppConst.CONST_IFKEYS[item.Value][0]))
                {
                    tlpContent = tlpContent.Replace(item.Value, AppConst.CONST_IFKEYS[item.Value][1]);
                }
                else
                {
                    tlpContent = tlpContent.Replace(item.Value, AppConst.CONST_IFKEYS[item.Value][2]);
                }
            }
            tlpContent = tlpContent.Replace("$NAMESPACE", tlpName);
            tlpContent = tlpContent.Replace("$TABLE_CHNAME", tableChName == "" ? tableName : tableChName);
            tlpContent = tlpContent.Replace("$TABLE_LOWER", tableName);
            tlpContent = tlpContent.Replace("$TABLE", tabName_FirstUp);
            tlpContent = tlpContent.Replace("$FK_DATATYPE", fkDataType);
            tlpContent = tlpContent.Replace("$SET_ALLCOLUMNS_R_FK", setAllColumnsRemoveFK.ToString());
            tlpContent = tlpContent.Replace("$SET_ALLCOLUMNS", setAllColumns.ToString());
            tlpContent = tlpContent.Replace("$SUMMARY_ALLCOLUMNS", summaryAllColumns.ToString());
            tlpContent = tlpContent.Replace("$PARAMCOLUMNS_TYPES", paramColumnsTypes.ToString().TrimEnd(','));
            tlpContent = tlpContent.Replace("$PARAMCOLUMNS_STRING_R_FK", paramColumnsStringRemoveFK.ToString().TrimEnd(','));
            tlpContent = tlpContent.Replace("$PARAMCOLUMNS_STRING", paramColumnsString.ToString().TrimEnd(','));
            tlpContent = tlpContent.Replace("$PARAMCOLUMNS", paramColumns.ToString().TrimEnd(','));
            tlpContent = tlpContent.Replace("$REQUEST_INIT_ALLCOLUMNS_PARAMS", requestInitParams.ToString());
            tlpContent = tlpContent.Replace("$REQUEST_CONVERT_COLUMNS_PARAMS", requestConvertParams.ToString());
            FileUtils.WriteFile(string.Format("{0}\\{1}{2}", codePath, tabName_FirstUp, fileExt), tlpContent);
        }

    }
}
